package rpg.core
{

	import flash.utils.Dictionary;
	
	import rpg.Utils.Log;
	import rpg.interfaces.IUpdate;
	import rpg.update.Update;

	public class GameBase extends Update
	{

		private var components : Array = [];
		private var typeComponent : Dictionary = new Dictionary(false);
		private var frameUpdatables : Array = [];
		private var gameObjectId : String;
		private var comIndex : int = 0;

		public function GameBase(id : String)
		{
			gameObjectId = id;
			super();
		}

		/**
		 * 为对象添加组件
		 * @param com
		 * @param priority
		 *
		 */
		public function addComponent(com : GameComponent , priority : int = 0) : void
		{
			if(!isActive)
				return;
			var index : int = components.indexOf(com);
			if(index != -1)
				return;
			components.push(com);
			com.index = comIndex++;
			if(com is IUpdate)
			{
				(com as IUpdate).priority = priority;
				frameUpdatables.push(com);
				if(priority != 0)
					frameUpdatables.sortOn(['priority' , 'index'] , [Array.NUMERIC | Array.DESCENDING , Array.NUMERIC]);
			}
			typeComponent[com.type] = com;
			com.owner = this;
			com.notifyAdded();
		}

		public function removeComponentByType(type : *) : void
		{
			removeComponent(getComponent(type));
		}

		public function removeComponent(com : GameComponent) : void
		{
			if(!isActive)
				return;
			if(com && typeComponent[com.type] == com && com.owner == this)
			{
				var index : int = components.indexOf(com);
				if(index != -1)
				{
					components.splice(index , 1);
				}
				index = frameUpdatables.indexOf(com);
				if(index != -1)
				{
					frameUpdatables.splice(index , 1);
				}
				delete typeComponent[com.type];
				com.owner = null;

				com.notifyRemoved(this);
			}
		}

		public function getComponent(type : *) : *
		{
			return typeComponent == null ? null : typeComponent[type];
		}

		private function notifyResetComponent() : void
		{
			for each(var com : GameComponent in components)
			{
				com.notifyReset();
			}
		}

		override public function update(elapsedTime : uint) : void
		{
			if(isDestroy)
				return;
			var len : int = frameUpdatables.length;
			for(var i : int = len - 1 ; i >= 0 ; i -= 1)
			{
				if(!frameUpdatables)
					break;
				var updatable : IUpdate = frameUpdatables[i];
				if(updatable.checkUpdatable(elapsedTime))
				{
					updatable.update(elapsedTime);
				}
			}
		}

		public function get isActive() : Boolean
		{
			return !isDestroy;
		}

		override public function destroy() : void
		{
			if(!isActive)
				return;
			unRegisterd();
			var len : int = components.length;
			for(var i : int = len - 1 ; i >= 0 ; i--)
			{
				var com : GameComponent = components[i];
				com.destroy();
			}
			_isDestroy = true;
			components.length = 0;
			frameUpdatables.length = 0;
			components = null;
			frameUpdatables = null;
			typeComponent = null;
			frameUpdatables = null;
		}
	}
}
